import java.util.Arrays;

/**
 * @作者 钟先崟
 * @时间 2023-02-05 13:45
 * @功能 31. 下一个排列
 * 整数数组的一个 排列  就是将其所有成员以序列或线性顺序排列。
 * 例如，arr = [1,2,3] ，以下这些都可以视作 arr 的排列：[1,2,3]、[1,3,2]、[3,1,2]、[2,3,1] 。
 * 整数数组的 下一个排列 是指其整数的下一个字典序更大的排列。更正式地，如果数组的所有排列根据其字典顺序从小到大排列在一个容器中，那么数组的 下一个排列 就是在这个有序容器中排在它后面的那个排列。如果不存在下一个更大的排列，那么这个数组必须重排为字典序最小的排列（即，其元素按升序排列）。
 * 例如，arr = [1,2,3] 的下一个排列是 [1,3,2] 。
 * 类似地，arr = [2,3,1] 的下一个排列是 [3,1,2] 。
 * 而 arr = [3,2,1] 的下一个排列是 [1,2,3] ，因为 [3,2,1] 不存在一个字典序更大的排列。
 * 给你一个整数数组 nums ，找出 nums 的下一个排列。
 * 必须 原地 修改，只允许使用额外常数空间。
 */
public class Solution
{
    public static void main(String[] args)
    {
//        int[] nums = new int[]{1, 2, 3};
//        int[] nums = new int[]{3, 2, 1};
//        int[] nums = new int[]{1, 1, 5};
        int[] nums = new int[]{1, 3, 2};
//        int[] nums = new int[]{1, 3, 2};
//        int[] nums = new int[]{5, 1, 3, 5, 4, 2};
        nextPermutation(nums);
        for (int i = 0; i < nums.length; i++)
        {
            System.out.print(nums[i] + " ");
        }
    }

    /**
     * 执行用时：
     * 1 ms
     * , 在所有 Java 提交中击败了
     * 35.07%
     * 的用户
     * 内存消耗：
     * 41.6 MB
     * , 在所有 Java 提交中击败了
     * 72.00%
     * 的用户
     * @param nums
     */
    public static void nextPermutation(int[] nums)
    {
        int x = -1;
        for (int i = nums.length - 1; i > 0; i--)
        {
            if (nums[i - 1] < nums[i])
            {
                x = i - 1;
                break;
            }
        }
        if (x == -1)
        {
            for (int i = 0, j = nums.length - 1; ; i++, j--)
            {
                if (i >= j) break;
                nums[i] = nums[j] + nums[i];
                nums[j] = nums[i] - nums[j];
                nums[i] = nums[i] - nums[j];
            }
        } else
        {
            int min = Integer.MAX_VALUE;
            int y = x;
            for (int i = x + 1; i < nums.length; i++)
            {
                if (nums[i] > nums[x] && nums[i] <= min)
                {
                    y = i;
                    min = nums[i];
                }
            }
            nums[x] = nums[x] + nums[y];
            nums[y] = nums[x] - nums[y];
            nums[x] = nums[x] - nums[y];
            Arrays.sort(nums, x + 1, nums.length);
        }
    }
}

